using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.Xml.Xsl;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Xml;
//using System.ComponentModel;
using Microsoft.SharePoint.Utilities;
using System.Globalization;

using SharePointOfView.Utilities;
using SharePointOfView.Properties;

namespace SharePointOfView.WebControls
{
    /// <summary>Base WebPart that applies XSL transform an XML string.</summary>
    /// <seealso cref="System.Web.UI.WebControls.WebParts.WebPart"/>
    /// <seealso cref="SharePointOfView.WebControls.WebPartBase"/>
    public abstract class XslTransformWebPart : WebPartBase
    {
        #region Private statements

        private string _xmlData = null;
        private string _Xsl = null;
        private int _cacheDuration;
        private Exception _preRenderException = null;
        private XsltArgumentList _xsltArguments = null;
        private string _htmlOutput = null;
        //private LocalizedWebDisplayNameAttribute webDisplayNameAttribute = new LocalizedWebDisplayNameAttribute("toto");


        #endregion

        #region Public properties

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        LocalizedWebDisplayName("XslWebPartXSLDisplayName"),
        LocalizedWebDescription("XslWebPartXSLDescription"),
        LocalizedCategoryAttribute("XslWebPartCategory")]
        public string Xsl
        {
            get
            {
                return _Xsl;
            }
            set
            {
                _Xsl = value;
            }
        }

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        LocalizedWebDisplayNameAttribute("XslWebPartCacheDurationDisplayName"),
        LocalizedWebDescriptionAttribute("XslWebPartCacheDurationDescription"),
        LocalizedCategoryAttribute("XslWebPartCategory")]
        public int CacheDuration
        {
            get
            {
                return _cacheDuration;
            }
            set
            {
                _cacheDuration = value;
            }
        }

        /// <summary>Arguments used in the XSL Transform process.</summary>
        protected XsltArgumentList XSLArguments
        {
            get
            {
                if (_xsltArguments == null)
                {
                    _xsltArguments = new XsltArgumentList();
                }
                return _xsltArguments;
            }
            set
            {
                _xsltArguments = value;
            }
        }

        /// <summary>Indicates is the data are stored in cache</summary>
        protected bool isInCache
        {
            get
            {
                return (CacheDuration > 0 && Context.Cache[this.UniqueID] != null);
            }
        }

        #endregion

        /// <summary>Get the xml data to transform.</summary>
        /// <returns>string formatted data.</returns>
        protected virtual string GetData()
        {
            return "<?xml version=\"1.0\" encoding=\"utf-8\" ?><xml/>";
        }

        

        /// <summary>Calls the GetData method if the cache is empty, then generates the HTML output string.</summary>
        /// <param name="e">Event argument</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            try
            {
                if (this.Xsl != null && this.Xsl != string.Empty)
                {
                    if (!this.isInCache)
                    {
                        _xmlData = this.GetData();
                        _htmlOutput = XSLT.XSLTransform(this._xmlData, this.Xsl, this.XSLArguments);

                        if (CacheDuration > 0)
                            Context.Cache.Insert(this.UniqueID, _htmlOutput, null, DateTime.Now.AddMinutes(CacheDuration), TimeSpan.Zero);
                    }
                    else
                    {
                        _htmlOutput = Context.Cache[this.UniqueID] as string;
                    }
                }
                else
                {
                    _htmlOutput = "<a id=\"" + this.Title + "_OpenToolPaneLink\" href=\"";
                    _htmlOutput = ((_htmlOutput + "javascript:MSOTlPn_ShowToolPane('1','") + SPHttpUtility.EcmaScriptStringLiteralEncode(this.ID) + "');\">") + Resources.ResourceManager.GetString("XslWebPartOpenToolPaneLink") +"</a>";
                    _htmlOutput = string.Format(CultureInfo.InvariantCulture, Resources.ResourceManager.GetString("XslWebPartXSLEmpty"), new object[] { _htmlOutput });
                }
            }
            catch (Exception ex)
            {
                _preRenderException = ex;
            }
        }

        /// <summary>Method rendering the WebPart HTML content.</summary>
        /// <param name="writer">the output stream Html writer</param>
        protected override void RenderWebPart(System.Web.UI.HtmlTextWriter writer)
        {
            if (_preRenderException != null)
            {
                throw _preRenderException;
            }
            
            writer.Write(_htmlOutput);
        }
    }
}
